home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Assassins - Ultimate CD Games Collection 2
/
Assassins 2 - Ultimate Games No. 2 (1995)(Weird Science)[!][Amiga-CD32-CDTV].iso
/
disks
/
wbgames4.dms
/
wbgames4.adf
/
MINESWEEPER
/
INIT.CC
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-29
|
10KB
|
337 lines
// This may look like C code, but it is really -*- C++ -*-
///////////////////////////////////////////////////////////////////////////
//
// AMIGA Minesweeper - Open window, init gadgets, ...
//
// (c) 1992 Hubert Feyrer (c9020@rrzc1.rz.uni-regensburg.de)
//
///////////////////////////////////////////////////////////////////////////
/*
** Diverse "C"-Header
*/
#define class _class
#define template _template
#define IntuitionBase IntuiBase
#define GfxBase GraphBase
extern "C" {
# include <stdio.h>
# include <stdlib.h>
# include <hardware/intbits.h>
# include <exec/types.h>
# include <exec/exec.h>
# include <exec/Interrupts.h>
# include <exec/Memory.h>
# include <exec/Ports.h>
# include <exec/ExecBase.h>
# include <devices/timer.h>
# include <utility/tagitem.h>
# include <intuition/intuition.h>
# include <intuition/intuitionbase.h>
# include <intuition/gadgetclass.h>
# include <graphics/view.h>
# include <libraries/gadtools.h>
# include <clib/gadtools_protos.h>
# include <clib/intuition_protos.h>
# include <clib/exec_protos.h>
# include <math.h>
}
#undef IntuitionBase
#undef GfxBase
#undef class
#undef template
/*
** C++-Header
*/
#include "mine.h"
#include "field.h"
#include <MLCG.h>
#include <RndInt.h>
//*
//* (zu) VIELE globale Daten...
//*
IntuiBase *IntuitionBase=NULL; // Typ NICHT IntuitionBase!!!
GraphBase *GfxBase=NULL; // Typ NICHT GfxBase!!!
Library *GadToolsBase=NULL;
NewWindow nwin={ 0,0,0,0,-1,-1,IDCMP_CLOSEWINDOW|IDCMP_GADGETUP|
IDCMP_MOUSEBUTTONS,WFLG_CLOSEGADGET|WFLG_OTHER_REFRESH
|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_ACTIVATE|WFLG_RMBTRAP
,NULL,NULL,NULL,NULL,NULL,0,0,0,0,WBENCHSCREEN };
Window *win=NULL;
Gadget *glist=NULL;
VisualInfo *vinfo=NULL;
Screen *scr=NULL;
timerequest treq; // Für Spielzeit-Anfrage
MsgPort *tport; // -"- ----"---- ---"---
int fxs=0; // field x size
int fys=0; // field y size
int X0; // linker Rand des Minenfeldes
int Y0; // rechter Rand des Minenfeldes
int win_w; // Breite des Spiel-Fensters
int win_h; // Höhe des Spiel-Fensters
char *argv0=NULL; // argv[0]
NewGadget nnumgad={ -1,-1,-1,-1,NULL,NULL,1000,PLACETEXT_IN,NULL,NULL};
Gadget *numgad=NULL; // Textgadget, um Restminen anzuzeigen
char tnumgad[5]; // minesleft
NewGadget ntimegad={ -1,-1,-1,-1,NULL,NULL,1001,PLACETEXT_IN,NULL,NULL};
Gadget *timegad=NULL; // Um Spielzeit anzuzeigen
char ttimegad[5]; // playtime
NewGadget ngogad={ -1,-1,-1,-1,NULL,NULL,1002,PLACETEXT_IN,NULL,NULL};
Gadget *gogad=NULL; // Restart-Button (nach Crash)
TextFont *txtfont; // mit setfont eingestellter Font
int countdown; // Restliche Felder
int minesleft; // Anzahl unentdeckter Minen
Offset validfields[]={ {-1,-1}, { 0,-1}, { 1,-1}, {-1, 0},
{ 1, 0}, {-1, 1}, { 0, 1}, { 1, 1} };
//*
//* Resourcen freigeben und Programm beenden.
//*
void shutdown(int rc, char *msg=NULL)
{
if(treq.tr_node.io_Message.mn_ReplyPort) CloseDevice((IORequest *)&treq);
if(tport) DeletePort((MsgPort *)tport);
if(win) CloseWindow(win);
if(glist) FreeGadgets(glist);
if(minefield){
for(int i=0;i<lenx;i++){
if(minefield[i]){
for(int j=0;j<leny;j++){
if(minefield[i][j]){
delete minefield[i][j];
}
}
delete[] minefield[i];
}
}
delete[] minefield;
}
if(vinfo) FreeVisualInfo(vinfo);
if(GadToolsBase) CloseLibrary(GadToolsBase);
if(GfxBase) CloseLibrary((Library *)GfxBase);
if(IntuitionBase) CloseLibrary((Library *)IntuitionBase);
msg && printf("%s: %s\n",argv0,msg);
exit(rc);
}
//*
//* Fenster, Gadget, ... initialisieren
//*
void init(int p)
{
ULONG lock;
int i,j;
// Diverse Bibliotheken öffnen
IntuitionBase=(IntuiBase *)OpenLibrary("intuition.library",37);
if(IntuitionBase==NULL) shutdown(20,"No OS2.0-Intuition found!");
GfxBase=(GraphBase *)OpenLibrary("graphics.library",37);
if(GfxBase==NULL) shutdown(20,"Need some OS2.0-Gfx!");
GadToolsBase=(Library *)OpenLibrary("gadtools.library",37);
if(GadToolsBase==NULL) shutdown(20,"Where's my GadTools-Library?!");
// Maßeinheiten ermitteln (f. Fenster, Gadgets, ...)
lock=LockIBase(0);
scr=IntuitionBase->ActiveScreen;
UnlockIBase(lock);
txtfont=(TextFont *)OpenFont(scr->Font); // Mit c:setfont festge-
// legter Zeichensatz
fxs=2*txtfont->tf_XSize;
if(scr->ViewPort.Modes&~LACE==0) fxs*=2; // LoRes
fys=txtfont->tf_YSize+3;
CloseFont(txtfont);
X0=1.5*fxs;
Y0=3*fys;
win_w=X0+(1.5*fxs)+(lenx*fxs);
win_h=Y0+fys+(leny*fys);
// Gadgets initialisieren
vinfo=GetVisualInfo(scr,TAG_END);
if(vinfo==NULL){
shutdown(20,"Can't GetVisualInfo()!");
}
Field::lastgad=CreateContext(&glist);
if( Field::lastgad==NULL ){
shutdown(20,"Can't CreateContext()!");
}
// Minenfeld errichten
countdown=0;
minefield=new Field **[lenx];
for(i=0;i<lenx;i++){
minefield[i]=new Field *[leny];
for(j=0;j<leny;j++){
minefield[i][j]=new Field(X0+i*fxs,Y0+j*fys,i,j);
}
}
// Minenanzeige-Gadget
sprintf(tnumgad,"%04d",(lenx*leny*p)/100);
if(tnumgad[0]=='0') tnumgad[0]=' ';
nnumgad.ng_VisualInfo = vinfo;
nnumgad.ng_TextAttr = scr->Font;
nnumgad.ng_LeftEdge = fxs;
nnumgad.ng_TopEdge = 1.45*fys;
nnumgad.ng_Width = 2.8*fxs;
nnumgad.ng_Height = fys;
Field::lastgad=numgad=CreateGadget(TEXT_KIND,Field::lastgad,&nnumgad,
GTTX_Text,tnumgad,
GTTX_Border, 2,
TAG_END);
if(numgad==NULL) shutdown(20,"Can't create numgad!");
// Zeitanzeige-Gadget
sprintf(ttimegad,"%04d",playtime);
ntimegad.ng_VisualInfo = vinfo;
ntimegad.ng_TextAttr = scr->Font;
ntimegad.ng_Width = 2.8*fxs;
ntimegad.ng_Height = fys;
ntimegad.ng_LeftEdge = win_w-(fxs+ntimegad.ng_Width);
ntimegad.ng_TopEdge = 1.45*fys;
Field::lastgad=timegad=CreateGadget(TEXT_KIND,Field::lastgad,&ntimegad,
GTTX_Text,ttimegad,
GTTX_Border, 2,
TAG_END);
if(numgad==NULL) shutdown(20,"Can't create timegad!");
// Restart-Button
ngogad.ng_VisualInfo = vinfo;
ngogad.ng_TextAttr = scr->Font;
ngogad.ng_GadgetText = "Go!";
ngogad.ng_Width = ntimegad.ng_LeftEdge-floor(5.4*fxs);
ngogad.ng_LeftEdge = 4.6*fxs;
ngogad.ng_TopEdge = 1.45*fys;
ngogad.ng_Height = fys;
Field::lastgad=gogad=CreateGadget(BUTTON_KIND,Field::lastgad,&ngogad,
TAG_END);
// gogad->Flags |= GFLG_DISABLED;
if(gogad==NULL) shutdown(20,"Can't create gogad!");
// Fenster aufmachen
nwin.Width = win_w;
nwin.Height = win_h;
nwin.LeftEdge = (scr->Width-win_w)/2;
nwin.TopEdge = (scr->Height-win_h)/2;
nwin.Title = WIN_T;
if(nwin.LeftEdge<=0 || nwin.TopEdge<=0)
shutdown(20,"Choose smaller dimension or font!");
nwin.FirstGadget = glist;
win=OpenWindowTags(&nwin,TAG_END);
if(win==NULL) shutdown(20,"Can't open window!");
// Timer-Device öffnen und Uhr initialisieren
tport=CreatePort("Mine timer-port",0);
if(tport==NULL) shutdown(20,"Can't create timer-port!");
if(OpenDevice("timer.device",UNIT_VBLANK,(IORequest *)&treq,0))
shutdown(20,"No timer.device?!?");
treq.tr_node.io_Message.mn_ReplyPort = tport;
treq.tr_node.io_Command = TR_ADDREQUEST;
treq.tr_node.io_Flags = 0;
treq.tr_node.io_Error = 0;
treq.tr_time.tv_secs = 1; // 1 Sekunde warten
treq.tr_time.tv_micro = 0;
playtime=0;
return;
}
//*
//* Felder aufdecken, Minen anzeigen
//*
void showmines(void)
{
for(int i=0;i<lenx;i++){
for(int j=0;j<leny;j++){
minefield[i][j]->open(1);
}
}
}
//*
//* Felder zuschütten, Markierung löschen
//*
void removemines(void)
{
for(int i=0;i<lenx;i++){
for(int j=0;j<leny;j++){
minefield[i][j]->clear();
}
}
RefreshGadgets(glist,win,NULL);
}
//*
//* Anzahl der Nachbarminen bei freien Feldern errechnen
//*
void calc_cnt(void)
{
for(int j=0;j<leny;j++){
for(int i=0;i<lenx;i++){
if(minefield[i][j]->cnt()!=-1){
int no=0; // Anzahl Minen in angrenzenden Feldern
// Umgebung jedes einzelnen Feldes absuchen
for(int v=0;v<8;v++){
int vi=i+validfields[v].dx;
int vj=j+validfields[v].dy;
if(inminefield(vi,vj)){
if(minefield[vi][vj]->cnt()==-1){
no++;
}
}
}
minefield[i][j]->cnt(no);
}
}
}
}
//*
//* Liefert Zufallszahl in [0;high) mit Algorithmus aus libg++
//*
int rnd(int high)
{
static MLCG gen(0,(long)time(NULL));
static RandomInteger r(0,65535,&gen);
return int(r.asLong(long(high-1)));
}
//*
//* Minenfeld zu p Prozent verminen und Anzahl Minen in
//* Nachbarfeldern berechnen lassen.
//*
void hidemines(int p)
{
int n=(lenx*leny*p)/100.0; // Anzahl zu legender Minen
minesleft=n;
while(n){
int x=rnd(lenx);
int y=rnd(leny);
if(minefield[x][y]->cnt()==-1) continue;
minefield[x][y]->cnt(-1);
--n;
}
calc_cnt();
}